/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
// r_surf.c: surface-related refresh code

#include "quakedef.h"


void R_DrawTextureChains (entity_t *e, float entalpha)
{
}


void R_AnimateTextures (model_t *m, int frame)
{
	texture_t *t;

	for (int i = 0; i < m->numtextures; i++)
	{
		if (!(t = m->textures[i])) continue;

		// and get the animation for this texture
		texture_t *anim = R_TextureAnimation (t, frame);

		// set the appropriate texture animation
		if (r_lightmap->boolean)
		{
			t->Animated[0] = &d3d_WhiteTexture;
			t->Animated[1] = NULL;
		}
		else
		{
			// and store them out so that we can reference them
			t->Animated[0] = anim->Texture[0];
			t->Animated[1] = anim->Texture[1];
		}
	}
}


void R_ChainSurface (msurface_t *surf, entity_t *e, float entalpha)
{
}


void R_MarkNodes (entity_t *e, mnode_t *node, msurface_t *surfaces)
{
	// no more nodes
	if (node->contents < 0) return;

	// mark the node as visible in this visframe so that lighting will pick it up
	node->visframe = ref.VisFrameCount;

	// find which side of the node we are on
	mplane_t *pplane = node->plane;
	float dot = Vector3Dot (e->modelorg, pplane->normal) - pplane->dist;

	// recurse down the tree, front-side first
	R_MarkNodes (e, node->children[(dot >= 0) ? 0 : 1], surfaces);

	msurface_t *surf = surfaces + node->firstsurface;

	for (int i = 0; i < node->numsurfaces; i++, surf++)
	{
		// because entities can reuse bmodels we need to explicitly clear the visframe
		if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))
			surf->visframe = -1;
		else surf->visframe = ref.FrameCount;
	}

	// recurse down the back side
	R_MarkNodes (e, node->children[(dot >= 0) ? 1 : 0], surfaces);
}


// these were split off so that RT lights can use them
BOOL R_ClipWorldNode (mnode_t *node, int &clipflags)
{
	if (node->contents == CONTENTS_SOLID) return FALSE;
	if (node->visframe != ref.VisFrameCount) return FALSE;

	if (clipflags)
	{
		for (int c = 0; c < 4; c++)
		{
			// don't need to clip against it
			if (!(clipflags & (1 << c))) continue;

			int side = BoxOnPlaneSide (node->mins, node->maxs, &ref.Frustum[c]);

			if (side == 1) clipflags &= ~(1 << c);	// node is entirely on screen
			if (side == 2) return FALSE;	// node is entirely off screen
		}
	}

	// node is entitely or partially on-screen
	return TRUE;
}


void R_HandleWorldLeaf (mleaf_t *leaf)
{
	int c;
	msurface_t **mark = leaf->firstmarksurface;

	if ((c = leaf->nummarksurfaces) > 0)
	{
		do
		{
			(*mark)->visframe = ref.FrameCount;
			mark++;
		} while (--c);
	}

	// deal with model and light fragments in this leaf
	if (leaf->efrags) R_StoreEfrags (&leaf->efrags);

	// update the water texture if necessary
	if (Mod_LeafIsUnderwater (ref.ViewLeaf[0]) &&
		!ref.WaterTexture &&
		!ref.ViewLeaf[0]->watertexture &&
		leaf->watertexture &&
		ref.ViewLeaf[0]->contents == leaf->contents)
		ref.WaterTexture = leaf->watertexture;
}


BOOL R_CullWorldSurface (msurface_t *surf, int clipflags, float dot)
{
	// check for culling conditions
	if (surf->visframe != ref.FrameCount) return TRUE;
	if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) return TRUE;
	if (R_CullBox (ref.Frustum, surf->mins, surf->maxs, clipflags)) return TRUE;

	// not culled
	return FALSE;
}


